﻿using GuiSearcher.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using GalaSoft.MvvmLight;

namespace GuiSearcher.Model {
    public class SearchCriteria : ViewModelBase {

        #region Constants

        /// <summary>
        /// The <see cref="Subject" /> property's name.
        /// </summary>
        public const string SubjectPropertyName = "Subject";

        /// <summary>
        /// The <see cref="IsSubjectRegEx" /> property's name.
        /// </summary>
        public const string IsSubjectRegExPropertyName = "IsSubjectRegex";

        /// <summary>
        /// The <see cref="TemperatureSearchMode" /> property's name.
        /// </summary>
        public const string TemperatureSearchModePropertyName = "TemperatureSearchMode";

        /// <summary>
        /// The <see cref="Temperature" /> property's name.
        /// </summary>
        public const string TemperaturePropertyName = "Temperature";

        /// <summary>
        /// The <see cref="AoiSearchMode" /> property's name.
        /// </summary>
        public const string AoiSearchModePropertyName = "AoiSearchMode";

        /// <summary>
        /// The <see cref="Aoi" /> property's name.
        /// </summary>
        public const string AoiPropertyName = "Aoi";

        /// <summary>
        /// The <see cref="Pola" /> property's name.
        /// </summary>
        public const string PolaPropertyName = "Pola";

        /// <summary>
        /// The <see cref="PolaSearchMode" /> property's name.
        /// </summary>
        public const string PolaSearchModePropertyName = "PolaSearchMode";

        /// <summary>
        /// The <see cref="ScansSearchMode" /> property's name.
        /// </summary>
        public const string ScansSearchModePropertyName = "ScansSearchMode";

        /// <summary>
        /// The <see cref="Scans" /> property's name.
        /// </summary>
        public const string ScansPropertyName = "Scans";

        /// <summary>
        /// The <see cref="ResolutionSearchMode" /> property's name.
        /// </summary>
        public const string ResolutionSearchModePropertyName = "ResolutionSearchMode";

        /// <summary>
        /// The <see cref="Resolution" /> property's name.
        /// </summary>
        public const string ResolutionPropertyName = "Resolution";

        /// <summary>
        /// The <see cref="Macro" /> property's name.
        /// </summary>
        public const string MacroPropertyName = "Macro";

        /// <summary>
        /// The <see cref="IsMacroRegEx" /> property's name.
        /// </summary>
        public const string IsMacroRegExPropertyName = "IsMacroRegEx";

        /// <summary>
        /// The <see cref="DateTime" /> property's name.
        /// </summary>
        public const string DateTimePropertyName = "DateTime";

        /// <summary>
        /// The <see cref="DateTimeSearchMode" /> property's name.
        /// </summary>
        public const string DateTimeSearchModePropertyName = "DateTimeSearchMode";

        private const bool IS_SUBJECT_REGEX_DEFAULT = true;
        private const bool IS_MACRO_REGEX_DEFAULT = true;
        private const SearchModeEnum TEMPERATURE_SEARCH_MODE_DEFAULT = SearchModeEnum.EQUAL;
        private const SearchModeEnum AOI_SEARCH_MODE_DEFAULT = SearchModeEnum.EQUAL;
        private const SearchModeEnum POLA_SEARCH_MODE_DEFAULT = SearchModeEnum.EQUAL;
        private const SearchModeEnum SCANS_SEARCH_MODE_DEFAULT = SearchModeEnum.EQUAL;
        private const SearchModeEnum RESOLUTION_SEARCH_MODE_DEFAULT = SearchModeEnum.EQUAL;
        private const SearchModeEnum DATE_TIME_SEARCH_MODE_DEFAULT = SearchModeEnum.EQUAL;
        private static readonly double? TEMPERATURE_DEFAULT = null;
        private static readonly double? AOI_DEFAULT = null;
        private static readonly double? POLA_DEFAULT = null;
        private static readonly int? SCANS_DEFAULT = null;
        private static readonly double? RESOLUTION_DEFAULT = null;
        private const string MACRO_DEFAULT = "";
        private const string SUBJECT_DEFAULT = "";
        private static readonly DateTime DATE_TIME_DEFAULT = DateTime.MinValue;

        #endregion


        #region Private Fields

        private bool _isSubjectRegex = IS_SUBJECT_REGEX_DEFAULT;
        private bool _isMacroRegEx = IS_MACRO_REGEX_DEFAULT;
        private DateTime _dateTime = DATE_TIME_DEFAULT;
        private string _subject = SUBJECT_DEFAULT;
        private SearchModeEnum _temperatureSearchMode = TEMPERATURE_SEARCH_MODE_DEFAULT;
        private double? _temperature = TEMPERATURE_DEFAULT;
        private SearchModeEnum _aoiSearchMode = AOI_SEARCH_MODE_DEFAULT;
        private double? _aoi = AOI_DEFAULT;
        private SearchModeEnum _polaSearchMode = POLA_SEARCH_MODE_DEFAULT;
        private double? _pola = POLA_DEFAULT;
        private SearchModeEnum _scansSearchMode = SCANS_SEARCH_MODE_DEFAULT;
        private int? _scans = SCANS_DEFAULT;
        private SearchModeEnum _resolutionSearchMode = RESOLUTION_SEARCH_MODE_DEFAULT;
        private double? _resolution = RESOLUTION_DEFAULT;
        private string _macro = MACRO_DEFAULT;
        private SearchModeEnum _dateTimeSearchMode = DATE_TIME_SEARCH_MODE_DEFAULT;

        #endregion

        #region Properties


        /// <summary>
        /// Sets and gets the Subject property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string Subject {
            get {
                return _subject;
            }

            set {
                if (_subject == value) {
                    return;
                }

                RaisePropertyChanging(SubjectPropertyName);
                _subject = value;
                RaisePropertyChanged(SubjectPropertyName);
            }
        }



        /// <summary>
        /// Sets and gets the IsSubjectRegEx property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IsSubjectRegex {
            get {
                return _isSubjectRegex;
            }

            set {
                if (_isSubjectRegex == value) {
                    return;
                }

                RaisePropertyChanging(IsSubjectRegExPropertyName);
                _isSubjectRegex = value;
                RaisePropertyChanged(IsSubjectRegExPropertyName);
            }
        }


        /// <summary>
        /// Sets and gets the TemperatureSearchMode property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public SearchModeEnum TemperatureSearchMode {
            get {
                return _temperatureSearchMode;
            }

            set {
                if (_temperatureSearchMode == value) {
                    return;
                }

                RaisePropertyChanging(TemperatureSearchModePropertyName);
                _temperatureSearchMode = value;
                RaisePropertyChanged(TemperatureSearchModePropertyName);
            }
        }




        

        /// <summary>
        /// Sets and gets the Temperature property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public double? Temperature {
            get {
                return _temperature;
            }

            set {
                if (_temperature == value) {
                    return;
                }

                RaisePropertyChanging(TemperaturePropertyName);
                _temperature = value;
                RaisePropertyChanged(TemperaturePropertyName);
            }
        }



        

        /// <summary>
        /// Sets and gets the AoiSearchMode property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public SearchModeEnum AoiSearchMode {
            get {
                return _aoiSearchMode;
            }

            set {
                if (_aoiSearchMode == value) {
                    return;
                }

                RaisePropertyChanging(AoiSearchModePropertyName);
                _aoiSearchMode = value;
                RaisePropertyChanged(AoiSearchModePropertyName);
            }
        }


        /// <summary>
        /// Sets and gets the Aoi property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public double? Aoi {
            get {
                return _aoi;
            }

            set {
                if (_aoi == value) {
                    return;
                }

                RaisePropertyChanging(AoiPropertyName);
                _aoi = value;
                RaisePropertyChanged(AoiPropertyName);
            }
        }



        /// <summary>
        /// Sets and gets the PolaSearchMode property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public SearchModeEnum PolaSearchMode {
            get {
                return _polaSearchMode;
            }

            set {
                if (_polaSearchMode == value) {
                    return;
                }

                RaisePropertyChanging(PolaSearchModePropertyName);
                _polaSearchMode = value;
                RaisePropertyChanged(PolaSearchModePropertyName);
            }
        }



        /// <summary>
        /// Sets and gets the Pola property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public double? Pola {
            get {
                return _pola;
            }

            set {
                if (_pola == value) {
                    return;
                }

                RaisePropertyChanging(PolaPropertyName);
                _pola = value;
                RaisePropertyChanged(PolaPropertyName);
            }
        }


        /// <summary>
        /// Sets and gets the ScansSearchMode property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public SearchModeEnum ScansSearchMode {
            get {
                return _scansSearchMode;
            }

            set {
                if (_scansSearchMode == value) {
                    return;
                }

                RaisePropertyChanging(ScansSearchModePropertyName);
                _scansSearchMode = value;
                RaisePropertyChanged(ScansSearchModePropertyName);
            }
        }


        /// <summary>
        /// Sets and gets the Scans property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public int? Scans {
            get {
                return _scans;
            }

            set {
                if (_scans == value) {
                    return;
                }

                RaisePropertyChanging(ScansPropertyName);
                _scans = value;
                RaisePropertyChanged(ScansPropertyName);
            }
        }



        /// <summary>
        /// Sets and gets the ResolutionSearchMode property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public SearchModeEnum ResolutionSearchMode {
            get {
                return _resolutionSearchMode;
            }

            set {
                if (_resolutionSearchMode == value) {
                    return;
                }

                RaisePropertyChanging(ResolutionSearchModePropertyName);
                _resolutionSearchMode = value;
                RaisePropertyChanged(ResolutionSearchModePropertyName);
            }
        }




        /// <summary>
        /// Sets and gets the Resolution property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public double? Resolution {
            get {
                return _resolution;
            }

            set {
                if (_resolution == value) {
                    return;
                }

                RaisePropertyChanging(ResolutionPropertyName);
                _resolution = value;
                RaisePropertyChanged(ResolutionPropertyName);
            }
        }



        /// <summary>
        /// Sets and gets the Macro property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string Macro {
            get {
                return _macro;
            }

            set {
                if (_macro == value) {
                    return;
                }

                RaisePropertyChanging(MacroPropertyName);
                _macro = value;
                RaisePropertyChanged(MacroPropertyName);
            }
        }





        /// <summary>
        /// Sets and gets the IsMacroRegEx property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IsMacroRegEx {
            get {
                return _isMacroRegEx;
            }

            set {
                if (_isMacroRegEx == value) {
                    return;
                }

                RaisePropertyChanging(IsMacroRegExPropertyName);
                _isMacroRegEx = value;
                RaisePropertyChanged(IsMacroRegExPropertyName);
            }
        }






        /// <summary>
        /// Sets and gets the DateTime property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public DateTime DateTime {
            get {
                return _dateTime;
            }

            set {
                if (_dateTime == value) {
                    return;
                }

                RaisePropertyChanging(DateTimePropertyName);
                _dateTime = value;
                RaisePropertyChanged(DateTimePropertyName);
            }
        }




        /// <summary>
        /// Sets and gets the DateTimeSearchMode property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public SearchModeEnum DateTimeSearchMode {
            get {
                return _dateTimeSearchMode;
            }

            set {
                if (_dateTimeSearchMode == value) {
                    return;
                }

                RaisePropertyChanging(DateTimeSearchModePropertyName);
                _dateTimeSearchMode = value;
                RaisePropertyChanged(DateTimeSearchModePropertyName);
            }
        }



        #endregion

        #region Public Methods


        public void Reset() {
            Subject = string.Empty;
            IsSubjectRegex = IS_SUBJECT_REGEX_DEFAULT;
            TemperatureSearchMode = TEMPERATURE_SEARCH_MODE_DEFAULT;
            Temperature = TEMPERATURE_DEFAULT;
            AoiSearchMode = AOI_SEARCH_MODE_DEFAULT;
            Aoi = AOI_DEFAULT;
            PolaSearchMode = POLA_SEARCH_MODE_DEFAULT;
            Pola = POLA_DEFAULT;
            ScansSearchMode = SCANS_SEARCH_MODE_DEFAULT;
            Scans = SCANS_DEFAULT;
            ResolutionSearchMode = RESOLUTION_SEARCH_MODE_DEFAULT;
            Resolution = RESOLUTION_DEFAULT;
            Macro = MACRO_DEFAULT;
            IsMacroRegEx = IS_MACRO_REGEX_DEFAULT;
            DateTimeSearchMode = DATE_TIME_SEARCH_MODE_DEFAULT;
            DateTime = DATE_TIME_DEFAULT;
        }

        #endregion

    }
}